import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class FileOperator {

	String baseLocation = "";

	public FileOperator(String baseLocation) {
		this.baseLocation = baseLocation;
	}

	public boolean genTheater(int teatroID, int rows, int columns)
			throws IOException {

		File file = new File(baseLocation + "teatro" + teatroID + ".txt");
		verificaPath(file);

		FileWriter fileW = new FileWriter(file);
		BufferedWriter bufw = new BufferedWriter(fileW);

		try {
			bufw.write("Nome: " + "teatro" + teatroID);
			bufw.newLine();
			bufw.write("NumLugares: " + (rows * columns));
			bufw.newLine();
			bufw.write("NumLugaresOcupados: 0");
			bufw.newLine();

			for (int i = 0; i < rows; i++) {
				bufw.write("-Row:" + i + " ");

				for (int j = 1; j <= columns; j++) {
					bufw.write(j + ":F ");
				}
				bufw.newLine();
			}
		} finally {
			bufw.close();
		}

		return true;
	}

	public boolean deleteTheater(int teatroID) {
		File file = new File(baseLocation + "teatro" + teatroID + ".txt");
		return file.delete();
	}

	// metodo para pesquisar por um unico teatro
	public Teatro getTheater(int teatroID, int totalColumns) throws IOException {

		String everything = "";
		String[] lines;
		String nome = "";
		int numLugares = 0;
		int lugaresOcupados = 0;

		ArrayList<Lugar> lugares = new ArrayList<Lugar>();
		int linha = 0, coluna = 0, estado = 0;

		everything = fileToString(teatroID);

		lines = everything.split("\n");

		for (String str : lines) {
			String args[] = str.split("\\s+");

			if (args[0].equals("Nome:")) {
				nome = args[1];
				continue;
			} else if (args[0].equals("NumLugares:")) {
				numLugares = Integer.parseInt(args[1]);
				continue;
			} else if (args[0].equals("NumLugaresOcupados:")) {
				lugaresOcupados = Integer.parseInt(args[1]);
				continue;
			}

			if (args[0].startsWith("-")) {
				linha = Integer.parseInt(args[0].split(":")[1]);

				for (int i = 1; i < args.length; i++) {

					coluna = Integer.parseInt(args[i].split(":")[0]);

					switch (args[i].split(":")[1].charAt(0)) {

					case 'F':
						estado = Lugar.STATE_FREE;
						break;

					case 'R':
						estado = Lugar.STATE_RESERVED;
						break;

					case 'B':
						estado = Lugar.STATE_BOUGHT;
						break;

					}

					lugares.add(new Lugar(linha * totalColumns + coluna, linha,
							coluna, estado));

				}
			}

		}

		Teatro theater = new Teatro(teatroID, numLugares, lugaresOcupados,
				nome, lugares);
		return theater;
	}

	// reserva de 1 lugar num teatro
	public boolean reserveSeat(int teatroID, int row, int col)
			throws IOException {

		String everything = fileToString(teatroID);
		String[] lines = everything.split("\n");
		boolean result = true;

		File file = new File(baseLocation + "teatro" + teatroID + ".txt");
		verificaPath(file);

		FileWriter fileW = new FileWriter(file);
		BufferedWriter bufw = new BufferedWriter(fileW);

		try {
			for (String str : lines) {
				if (str.startsWith("-Row:" + row)) {

					String[] args = str.split("\\s+");

					for (int i = 0; i < args.length; i++) {
						if (args[i].startsWith(Integer.toString(col))) {
							String[] seatParams = args[i].split(":");

							switch (seatParams[1].charAt(0)) {
							case 'F':
								seatParams[1] = "R";
								break;
							default:
								result = false;
								break;
							}

							for (int j = 0; j < seatParams.length; j++)
								if (j == seatParams.length - 1
										&& i == args.length - 1) {
									bufw.write(seatParams[j]);
									bufw.newLine();
								} else if (j == seatParams.length - 1)
									bufw.write(seatParams[j] + " ");
								else
									bufw.write(seatParams[j] + ":");

						} else if (i == args.length - 1) {
							bufw.write(args[i]);
							bufw.newLine();
						} else
							bufw.write(args[i] + " ");
					}

				} else {
					bufw.write(str);
					bufw.newLine();
				}
			}
		} finally {
			bufw.close();
		}

		return result;
	}

	// compra de 1 lugar num teatro
	public boolean purchaseSeat(int teatroID, int row, int col)
			throws IOException {

		String everything = fileToString(teatroID);
		String[] lines = everything.split("\n");
		boolean result = true;

		File file = new File(baseLocation + "teatro" + teatroID + ".txt");
		verificaPath(file);

		FileWriter fileW = new FileWriter(file);
		BufferedWriter bufw = new BufferedWriter(fileW);

		try {
			for (String str : lines) {
				if (str.startsWith("-Row:" + row)) {

					String[] args = str.split("\\s+");

					for (int i = 0; i < args.length; i++) {
						if (args[i].startsWith(Integer.toString(col))) {
							String[] seatParams = args[i].split(":");

							switch (seatParams[1].charAt(0)) {
							case 'F':
								seatParams[1] = "B";
								break;
							default:
								result = false;
								break;
							}

							for (int j = 0; j < seatParams.length; j++)
								if (j == seatParams.length - 1
										&& i == args.length - 1) {
									bufw.write(seatParams[j]);
									bufw.newLine();
								} else if (j == seatParams.length - 1)
									bufw.write(seatParams[j] + " ");
								else
									bufw.write(seatParams[j] + ":");

						} else if (i == args.length - 1) {
							bufw.write(args[i]);
							bufw.newLine();
						} else
							bufw.write(args[i] + " ");
					}

				} else {
					bufw.write(str);
					bufw.newLine();
				}
			}
		} finally {
			bufw.close();
		}
		return result;
	}

	public void verifyReservation(int tempo, int seatID) {

	}

	public String getTheaterName(int teatroID) throws IOException {

		String str;
		Path filePath = Paths.get(baseLocation + "teatro" + teatroID + ".txt",
				"");
		BufferedReader br = Files.newBufferedReader(filePath,
				Charset.forName("UTF-8"));

		try {
			while ((str = br.readLine()) != null) {
				String[] args = str.split("\\s+");
				if (args[0].equals("Nome:"))
					return args[1];
			}
		} finally {
			br.close();
		}
		return null;
	}

	/**
	 * devolve path do file sem o nome deste
	 * 
	 * @param file
	 * @return str- path do file
	 */
	public static String path(File file) {
		boolean flag = true;
		String str = "";
		StringTokenizer s = new StringTokenizer(file.getPath(), "/");

		while (s.hasMoreTokens()) {
			String aux = s.nextToken();
			if (!aux.equals(file.getName()))
				if (flag) {
					str += aux;
					flag = false;
				} else
					str += "/" + aux;
		}

		return str;
	}

	/**
	 * verifica se um dado caminho existe. Senao existir cria o caminho
	 * 
	 * @param file
	 */
	public static void verificaPath(File file) {
		String str = "";
		str = path(file);
		if (!file.exists()) {
			new File(str).mkdirs();
		}

	}

	private String fileToString(int teatroID) throws IOException {
		String everything = "";

		Path filePath = Paths.get(baseLocation + "teatro" + teatroID + ".txt",
				"");
		BufferedReader br = Files.newBufferedReader(filePath,
				Charset.forName("UTF-8"));

		try {
			StringBuilder sb = new StringBuilder();
			String line = br.readLine();

			while (line != null) {
				sb.append(line);
				sb.append('\n');
				line = br.readLine();
			}
			everything = sb.toString();
		} finally {
			br.close();
		}

		return everything;
	}
}
